package com.ffcs.crmd.tsp.core.netty.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ffcs.crmd.tsp.api.netty.INettyRemotingServer;
import com.ffcs.crmd.tsp.common.constant.LoggerName;
import com.ffcs.crmd.tsp.common.netty.NettyEvent;
import com.ffcs.crmd.tsp.common.netty.enu.NettyEventType;
import com.ffcs.crmd.tsp.core.util.RemotingUtil;

import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

/**
 * 
 * 功能说明:通信服务器事件处理
 *
 * @author ZHONGFUHUA
 * 
 * @since 1.0.0-SNAPSHOT
 *
 */
public class NettyConnetManageHandler extends ChannelDuplexHandler {
    
    /**
     * 日志
     */
    private Logger               log = LoggerFactory.getLogger(LoggerName.RemotingLoggerName);
    
    /**
     * 通信服务端
     */
    private INettyRemotingServer remotingServer;
    
    public NettyConnetManageHandler(INettyRemotingServer remotingServer) {
        this.remotingServer = remotingServer;
    }
    
    /**
     * 
     * 功能说明:新客户端注册
     * 
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        log.info("SERVER-NETTY: new channel{} registered", ctx.channel());
        super.channelRegistered(ctx);
    }
    
    
    
    /**
     * 
     * 功能说明:客户端注销
     * 
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        log.info("SERVER-NETTY: one channel{} unregistered", ctx.channel());
        super.channelUnregistered(ctx);
    }
    
    /**
     * 
     * 功能说明:有新客户端连接激活
     * 
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("SERVER-NETTY: new channel{} active", ctx.channel());
        super.channelActive(ctx);
    }
    
    /**
     * 
     * 功能说明:客户端断开连接失效
     * 
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        final String remoteAddress = RemotingUtil.parseChannelRemote(ctx.channel());
        log.info("SERVER-NETTY: one channel{} inactive", ctx.channel());
        remotingServer.putNettyEvent(new NettyEvent(NettyEventType.CLOSE, remoteAddress, ctx.channel()));
        super.channelInactive(ctx);
    }
    
    /**
     * 
     * 功能说明:处理IDLE事件
     * 
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent evnet = (IdleStateEvent) evt;
            if (evnet.state().equals(IdleState.ALL_IDLE)) {
                final String remoteAddress = RemotingUtil.parseChannelRemote(ctx.channel());
                log.warn("SERVER-NETTY: channel{} occur a idle event:{}", ctx.channel(), evnet);
                remotingServer.putNettyEvent(new NettyEvent(NettyEventType.IDLE, remoteAddress, ctx.channel()));
            }
        }else{
            ctx.fireUserEventTriggered(evt);
        }
    }
    
    /**
     * 
     * 功能说明:处理异常事件
     * 
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        final String remoteAddress = RemotingUtil.parseChannelRemote(ctx.channel());
        log.warn("SERVER-NETTY: channel{} occur a exception:", ctx.channel(), cause);
        remotingServer.putNettyEvent(new NettyEvent(NettyEventType.EXCEPTION, remoteAddress, ctx.channel()));
    }
    
}
